// 场景尺寸
import * as THREE from "three";
// @ts-ignore
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";

let W = window.innerWidth
let H = window.innerHeight

const init = (sceneContainer: HTMLDivElement, imgLink: string) => {
    // 场景
    const scene = new THREE.Scene()

    const loader = new THREE.TextureLoader();
    const texture = loader.load(
        imgLink,
        /**
         * 设置场景的背景纹理为球形反射贴图，并指定颜色空间。
         * 这段代码通过配置纹理的映射方式和颜色空间，来影响场景中物体的反射效果和颜色表现。
         */
        () => {
            texture.mapping = THREE.EquirectangularReflectionMapping;
            texture.colorSpace = THREE.SRGBColorSpace;
            scene.background = texture;
        });


    // 控制器参数
    const minSpeed = -0.05              // 最大缩放下的最小旋转速度
    const maxSpeed = -0.8                // 最小缩放下的最大旋转速度
    const minFov = 10;                  // fov的最小值
    const maxFov = 120;                 // fov的最大值
    const minDistance = 1               // 最小缩放距离
    const maxDistance = 10              // 最大缩放距离

    // 相机
    const camera = new THREE.PerspectiveCamera()
    camera.far = 1000
    camera.near = 0.001
    camera.aspect = W / H
    camera.fov = maxFov
    camera.position.set(maxDistance, 0, 0)
    camera.lookAt(0, 0, 0)
    camera.updateProjectionMatrix()

    // 渲染器
    const renderer = new THREE.WebGLRenderer()
    renderer.setSize(W, H)

    // 控制器
    const controller = new OrbitControls(camera, renderer.domElement)
    controller.enablePan = false        // 启用移动
    controller.enableZoom = true        // 启用缩放
    controller.enableRotate = true      // 启用旋转
    controller.rotateSpeed = -1         // 旋转速度
    controller.enableDamping = false    // 启用惯性
    controller.minDistance = 1          // 最小缩放距离
    controller.maxDistance = 10         // 最大缩放距离
    controller.autoRotateSpeed = 0.5    // 自动旋转速度

    sceneContainer.appendChild(renderer.domElement)

    // 场景自适应窗口
    let timer = null
    window.addEventListener('resize', () => {
        window.clearTimeout(timer)
        timer = window.setTimeout(() => {
            W = window.innerWidth
            H = window.innerHeight
            renderer.setSize(W, H)
            camera.aspect = W / H
            camera.updateProjectionMatrix()
        }, 50)
    })

    // 缩放场景
    controller.addEventListener('change', () => {
        const zoomFactor = camera.position.distanceTo(controller.target);
        // 根据缩放因子调整相机的视野
        let newFov = THREE.MathUtils.mapLinear(zoomFactor, controller.minDistance, controller.maxDistance, minFov, maxFov);
        newFov = THREE.MathUtils.clamp(newFov, minFov, maxFov); // 确保fov在合理范围内
        // 根据缩放的fov调整旋转速度
        controller.rotateSpeed = THREE.MathUtils.mapLinear(newFov, minFov, maxFov, minSpeed, maxSpeed);

        camera.fov = newFov;
        camera.updateProjectionMatrix(); // 必须在更改fov后更新相机的投影矩阵
    })

    // 渲染函数
    let stop = false
    const renderScene = () => {
        controller.update()
        renderer.render(scene, camera)
        if (!stop) {
            window.requestAnimationFrame(renderScene)
        }
    }
    renderScene()

    return {
        dispose: () => {
            stop = true
            texture.dispose()
            controller.dispose()
            renderer.domElement.remove()
            renderer.dispose()
        },
        autoRotate: (flag: boolean) => {
            controller.autoRotate = flag;
        }
    }
}

// 手动缩放场景
// const zoom = (evt: {deltaY: number}) => {
//     camera.fov += evt.deltaY * 0.1
//     if (camera.fov < 20) {
//         camera.fov = 20
//     } else if (camera.fov > 120) {
//         camera.fov = 120
//     }
//     camera.updateProjectionMatrix()
// }
// renderer.domElement.addEventListener("wheel", zoom)

// 测试代码
// const box3 = new THREE.BoxGeometry();
// const met = new THREE.MeshBasicMaterial();
// const obj = new THREE.Mesh(box3, met)
// scene.add(obj)

export default init